package com.dingding.common.core.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import com.dingding.common.core.config.ImageUploadConfig;
import com.dingding.common.core.config.SystemCode;
import com.dingding.common.core.util.paravalidate.ValiResult;
import com.dingding.common.core.util.paravalidate.ValidateUtil;
import com.dingding.common.core.util.tools.wechat.WechatTool;

/**
 * 
 * @ClassName: Tool
 * @Description: 工具验证类
 * @author cheshaowei
 * @date 2015-5-11 下午05:42:59
 */
public class ToolUtil {

	private static Logger log = Logger.getLogger(ToolUtil.class);

	/**
	 * 
	 * @Title: isBlank
	 * @Description: 判断字符串是否为空
	 * @return boolean true:空 false:不为空
	 * 
	 */
	public static boolean isBlank(String str) {
		if (StringUtils.isBlank(str)) {
			return true;
		}
		return false;
	}

	/**
	 * 
	 * @Description: 判断字符串是否为空
	 * @return boolean true:不为空 false:为空
	 * 
	 */
	public static boolean isNotBlank(String str) {
		if (StringUtils.isNotBlank(str)) {
			return true;
		}
		return false;
	}

	/***
	 * 
	 * @Title: isNotNullObj
	 * @Description: 判断可变参数是否为空
	 * @param object
	 * @return boolean
	 * 
	 */
	public static boolean isNotNullObj(Object[] param) {
		if (param != null && param.length != 0) {
			return true;
		}
		return false;
	}

	/**
	 * 
	 * @Description: 判断对象是否为空
	 * @return true: 空 false ：不为空
	 * @return boolean
	 * 
	 */
	public static boolean isNullObject(Object object) {
		return object == null ? true : false;
	}

	/**
	 * 
	 * @Description: 校验Map集合中是否存在空值
	 * @return boolean true 存在空值 false 不存在空值
	 * @date 2016年12月29日
	 * @author CHEHUANBO
	 * @version V2.6.4
	 * 
	 */
	public static boolean validateMapValueIsBlank(Map<String, Object> map) {

		if (map == null) {
			return false;
		}

		for (Map.Entry<String, Object> entry : map.entrySet()) {
			String name = entry.getKey();
			if (name == null) {
				continue;
			}
			Object obj = entry.getValue();
			if (obj == null) {
				return true;
			}
		}

		return false;

	}

	/**
	 * 
	 * @Title: castDouble
	 * @Description: Object类型转换成Double类型
	 * @return Double 转换后的值
	 * 
	 */
	public static Double castDouble(Object object) {
		return ToolUtil.isNotBlank(object.toString()) ? Double.valueOf(object.toString()) : null;
	}

	/**
	 * 
	 * @Title: castDouble
	 * @Description: Object类型转换成Double类型
	 * @return Double 转换后的值
	 * 
	 */
	public static Float castFloat(Object object) {
		return ToolUtil.isNotBlank(object.toString()) ? Float.valueOf(object.toString()) : null;
	}

	/**
	 * 
	 * @Description: Object类型转换成Integer类型
	 * @param Double
	 *            转换后的值
	 * 
	 */
	public static Integer castInteger(Object object) {

		return ToolUtil.isNotBlank(object.toString()) ? Integer.valueOf(object.toString()) : null;
	}

	/**
	 * @Description: 验证参数是否为空
	 * @author fengshuonan
	 * @return boolean true 参数有为空的 false 参数没有空的
	 */
	public static boolean validateParas(Object... objs) {

		for (Object obj : objs) {
			if (obj == null) {
				return true;
			}

			if (obj instanceof String) {
				if (ToolUtil.isBlank(obj.toString())) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 
	 * @Title: generateCellPhoneValidateNum
	 * @Description: 生成手机6位随机数
	 * @return Integer
	 * 
	 */
	public static String generateCellPhoneValNum() {

		String[] beforeShuffle = new String[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };
		List<String> list = Arrays.asList(beforeShuffle);
		Collections.shuffle(list);
		StringBuilder buffer = new StringBuilder();
		for (int i = 0; i < list.size(); i++) {
			buffer.append(list.get(i));
		}
		String afterShuffle = buffer.toString();
		String result = afterShuffle.substring(3, 7);
		return result;

	}

	/**
	 * 
	 * @Title: validateTimeOut
	 * @Description: 验证手机验证码是否超时
	 * @param expireTime
	 *            验证码创建时间
	 * @return true 未超时 false 超时
	 * 
	 */
	public static boolean validateTimeOut(Date expireTime) {

		Calendar rightNow_1 = Calendar.getInstance();

		// 验证码创建时间加10分钟获得验证码过期时间
		rightNow_1.setTime(expireTime);
		rightNow_1.add(Calendar.MINUTE, SystemCode.PHONE_VALIDATE_EXPIRE_TIME);

		// 获取系统当前时间
		Date currdentTime = new Date();
		Calendar rightNow_2 = Calendar.getInstance();
		rightNow_2.setTime(currdentTime);
		return rightNow_2.before(rightNow_1);
	}

	/**
	 * 
	 * 拼接图片访问名称
	 * 
	 * 说明：2016-05-25 修改(CHEHUANBO)
	 * 
	 * @param name
	 *            图片名称
	 * @author CHEHUANBO
	 * @return String 拼接后的图片访问地址
	 * 
	 */
	public static String imageAddress(String name) {

		StringBuffer str = new StringBuffer(ImageUploadConfig.getIMAGE_ACCESS_PATH());
		str.append(name);

		return str.toString();
	}

	/**
	 * 
	 * @Title: creatImageName
	 * @Description: 生成图片名称
	 * @author lijinchao
	 * 
	 */
	public static String creatImageName() {

		StringBuffer str = new StringBuffer(getUid());
		str.append(".jpg");

		return str.toString();
	}

	/**
	 * 
	 * @Title: getUid
	 * @Description: 获取uid
	 * @author lijinchao
	 * 
	 */
	public static synchronized String getUid() {
		return DateFormatUtil.getTimeInMillis().toString() + generateCellPhoneValNum();
	}

	/**
	 * 
	 * @Title: keepPlaces
	 * @Description: Double类型保留两位小数
	 * @param
	 * @author yuHaiQing
	 * @return Double
	 * 
	 */
	public static Double keepPlaces(Double param) {

		if (param == null) {
			return param;
		}

		DecimalFormat formater = new DecimalFormat();
		// 保留几位小数
		formater.setMaximumFractionDigits(1);
		// 模式 四舍五入
		formater.setRoundingMode(RoundingMode.UP);

		return Double.parseDouble(formater.format(param).replace(",", ""));

	}

	/**
	 * 
	 * @Title: keepPlaces
	 * @Description: Double类型保留一位位小数
	 * @param param
	 * @author yuHaiQing
	 * @return Double
	 * 
	 */
	public static Double keepOnePlaces(Double param) {

		if (param == null) {
			return param;
		}

		DecimalFormat formater = new DecimalFormat("00.00");
		// 保留几位小数
		formater.setMaximumFractionDigits(1);
		// 模式 四舍五入
		formater.setRoundingMode(RoundingMode.UP);

		return Double.parseDouble(formater.format(param));

	}

	/**
	 * @Title: keepPlaces
	 * @Description: Double类型保留一位位小数(向下取整)
	 * @param param
	 * @author yuHaiQing
	 * @return Double
	 */
	public static Double keepOnePlacesDown(Double param) {

		if (param == null) {
			return param;
		}

		DecimalFormat formater = new DecimalFormat("00.00");
		// 保留几位小数
		formater.setMaximumFractionDigits(1);
		// 模式 四舍五入
		formater.setRoundingMode(RoundingMode.DOWN);

		return Double.parseDouble(formater.format(param));

	}

	/**
	 * @Title: randomLenStr
	 * @Description: 生成随机长度字符串
	 * @param length
	 *            长度
	 * @author fengshuonan
	 */
	public static String randomLenStr(int maxLength) {

		String source = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
		StringBuffer buffer = new StringBuffer("");
		Random random = new Random();
		for (int i = 0; i < maxLength; i++) {
			buffer.append(source.charAt(random.nextInt(source.length())));
		}
		return buffer.toString();
	}

	/**
	 * @Title: randomLenStr
	 * @Description: 生成随机长度字符串
	 * @param length
	 *            长度
	 * @author fengshuonan
	 */
	public static String randomLenLetter(int maxLength) {

		String source = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
		StringBuffer buffer = new StringBuffer("");
		Random random = new Random();
		for (int i = 0; i < maxLength; i++) {
			buffer.append(source.charAt(random.nextInt(source.length())));
		}
		return buffer.toString();
	}

	/**
	 * @Title: lexSort
	 * @Description: 对一系列字符串进行字典排序
	 * @param list
	 *            被排序的数组
	 * @author fengshuonan
	 */
	public static void lexSort(List<String> list) {
		Collections.sort(list, new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				return o1.compareTo(o2);
			}
		});
	}

	/**
	 * @Title: lexSortBean
	 * @Description:对bean里的所有非空字段进行字典排序， 返回结果为URL键值对的格式
	 * @param obj
	 *            被字典排序的bean
	 * @author fengshuonan
	 * @return String 返回示例（key1=value1&key2=value2....）
	 */
	public static String lexSortBean(Object obj, Class<?> clazz) {

		List<String> list = new ArrayList<String>();
		Field[] fields = clazz.getDeclaredFields();

		// 反射获取对象的所有非空字段，并存放到一个list容器里
		try {
			for (Field field : fields) {
				field.setAccessible(true);
				if (field.get(obj) != null) {
					list.add(field.getName() + "=" + field.get(obj));
				}
			}
		} catch (Exception e) {
			log.error("对bean字典排序的时候出错！ToolUtil:lexSortBean()", e);
			return null;
		}

		// 对list内所有进行字典排序
		ToolUtil.lexSort(list);

		// 把list数据都用&拼接
		StringBuffer stringBuffer = new StringBuffer("");
		for (String str : list) {
			stringBuffer.append(str + "&");
		}

		return stringBuffer.toString();
	}

	/**
	 * @Title: lexSortBean
	 * @Description:对bean里的所有非空字段进行字典排序， 返回结果为URL键值对的格式
	 * @param obj
	 *            被字典排序的bean
	 * @author fengshuonan
	 * @return String 返回示例（key1=value1&key2=value2....）
	 */
	public static String lexSortBean(Object obj, Class<?> clazz, String append) {

		List<String> list = new ArrayList<String>();
		Field[] fields = clazz.getDeclaredFields();

		// 反射获取对象的所有非空字段，并存放到一个list容器里
		try {
			for (Field field : fields) {
				field.setAccessible(true);
				if (field.get(obj) != null) {
					list.add(field.getName() + "=" + field.get(obj));
				}
			}
		} catch (Exception e) {
			log.error("对bean字典排序的时候出错！ToolUtil:lexSortBean()", e);
			return null;
		}

		// 添加附加的条件
		list.add(append);

		// 对list内所有进行字典排序
		ToolUtil.lexSort(list);

		// 把list数据都用&拼接
		StringBuffer stringBuffer = new StringBuffer("");
		for (String str : list) {
			stringBuffer.append(str + "&");
		}

		return stringBuffer.toString();
	}

	/**
	 * @Title: firstLetterToUpper
	 * @Description: 把首字母大写
	 * @param value
	 *            被修改的字符串
	 * @author fengshuonan
	 * @return String 修改后的字符串
	 */
	public static String firstLetterToUpper(String value) {

		// 拆分字符串为两部分
		String str1 = value.substring(0, 1);
		String str2 = value.substring(1);

		// 第一部分大写
		str1 = str1.toUpperCase();

		return str1 + str2;
	}

	/**
	 * @Description: 把首字母小写
	 * @param value
	 *            被修改的字符串
	 * @author fengshuonan
	 * @return String 修改后的字符串
	 */
	public static String firstLetterToLowwer(String value) {

		// 拆分字符串为两部分
		String str1 = value.substring(0, 1);
		String str2 = value.substring(1);

		// 第一部分小写
		str1 = str1.toLowerCase();

		return str1 + str2;
	}

	/**
	 * @Title: getRandString
	 * @Description:获得指定长度随机字符串
	 * @param maxLength
	 *            指定位数
	 * @author fengshuonan
	 * @return String 随机字符串
	 */
	public static String getRandString(int maxLength) {
		String source = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
		StringBuffer buffer = new StringBuffer("");
		Random random = new Random();
		for (int i = 0; i < maxLength; i++) {
			buffer.append(source.charAt(random.nextInt(source.length())));
		}
		return buffer.toString();
	}

	/**
	 * @Title: readStreamToText
	 * @Description:读取流里的信息，并返回为字符串形式
	 * @author fengshuonan
	 * @return String 流内信息的字符串形式
	 */
	public static String readStreamToText(InputStream inputStream) {

		InputStreamReader input = null;
		BufferedReader bufferedReader = null;

		try {
			// 获得请求的字符流
			input = new InputStreamReader(inputStream, "UTF-8");
			bufferedReader = new BufferedReader(input);

			// 接收xml，循环读出xml全部内容
			StringBuffer xml = new StringBuffer();
			String line = bufferedReader.readLine();
			while (line != null) {
				xml.append(line);
				line = bufferedReader.readLine();
			}
			return xml.toString();

		} catch (IOException e) {
			e.printStackTrace();
			return "";
		} finally {
			try {
				if (bufferedReader != null) {
					bufferedReader.close();
				}
				if (input != null) {
					input.close();
				}
				if (inputStream != null) {
					input.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
	}

	/**
	 * @Title: getSignature
	 * @Description: 获取jssdk调用的签名(获得签名参数拼接顺序为jsapi_ticket,noncestr,timestamp,
	 *               url)
	 * @author fengshuonan
	 * @return String
	 */
	public static String getSignature(String noncestr, String timestamp, String url) {

		String jsapi_ticket = WechatTool.getJsapi_ticket();

		String jsapi_ticketVal = "jsapi_ticket=" + jsapi_ticket;
		String noncestrVal = "noncestr=" + noncestr;
		String timestampVal = "timestamp=" + timestamp;
		String urlVal = "url=" + url;

		List<String> list = new ArrayList<String>();
		list.add(jsapi_ticketVal);
		list.add(noncestrVal);
		list.add(timestampVal);
		list.add(urlVal);

		// 字典顺序排序
		ToolUtil.lexSort(list);
		String result = list.get(0) + "&" + list.get(1) + "&" + list.get(2) + "&" + list.get(3);
		String encode = SHA1Util.sha1Hex(result);
		return encode;
	}

	/**
	 * 
	 * @Title: uuid
	 * @Description: 生成UUID
	 * @return String 生成的UUID
	 * @author CHEHAUNBO
	 * 
	 */
	public static String uuid() {

		return UUID.randomUUID().toString();
	}

	/**
	 * 
	 * 验证客户端请求参数是否合法
	 * 
	 * @Title: validateParam
	 * @author YHQ
	 * @since V2.5.7
	 * 
	 */
	public static boolean validateParam(Object object) {

		ValiResult valiResult = ValidateUtil.validateBeanIsAvaliable(object, object.getClass());

		if (valiResult != null && !valiResult.isAvailable()) {// 参数为空
			return false;
		}

		return true;
	}

	/**
	 * @Title: readStreamToText
	 * @Description:读取流里的信息，并返回为字符串形式
	 * @author fengshuonan
	 * @return String 流内信息的字符串形式
	 */
	public static String readStreamToText(InputStream inputStream, String encode) {

		InputStreamReader input = null;
		BufferedReader bufferedReader = null;

		try {
			// 获得请求的字符流
			input = new InputStreamReader(inputStream, encode);
			bufferedReader = new BufferedReader(input);

			// 接收xml，循环读出xml全部内容
			StringBuffer xml = new StringBuffer();
			String line = bufferedReader.readLine();
			while (line != null) {
				xml.append(line);
				line = bufferedReader.readLine();
			}
			return xml.toString();

		} catch (IOException e) {
			e.printStackTrace();
			return "";
		} finally {
			try {
				if (bufferedReader != null) {
					bufferedReader.close();
				}
				if (input != null) {
					input.close();
				}
				if (inputStream != null) {
					input.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
	}

	/**
	 * 
	 * @Title: getNullPropertyNames
	 * @Description: 获取空值得属性字段
	 * @param source
	 * @return 参数说明
	 * @return String[] 返回类型
	 */
	public static String[] getNullPropertyNames(Object source) {
		final BeanWrapper src = new BeanWrapperImpl(source);
		java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

		Set<String> emptyNames = new HashSet<String>();
		for (java.beans.PropertyDescriptor pd : pds) {
			Object srcValue = src.getPropertyValue(pd.getName());
			if (srcValue == null)
				emptyNames.add(pd.getName());
		}
		String[] result = new String[emptyNames.size()];
		return emptyNames.toArray(result);
	}
}